import os,sys
from PIL import Image

from glue2 import *
import time
import random
from threading import Thread, Lock, currentThread

backspath="c:\\_haven\\map\\back\\"
v=dict()                                  
maxstiched=0
mx,my=0,0

deltaX=deltaY=125

def calcCoords(dx,dy,d):
    dd=d-1
    x1=x3=y1=y3=0
    if dx>dd:
        x1=dx-d
        x2=dd
        x4=2*dd-dx
    else:
        x3=d-dx
        x2=dx
        x4=dd

    if dy>dd:
        y1=dy-dd
        y2=dd
        y4=2*dd-dy
    else:
        y3=dd-dy
        y2=dy
        y4=dd
        
    return ((x1,y1),(x2,y2),(x3,y3),(x4,y4))

def overLaps(im1,im2,dd):
    """ overlaps two sqare imaged width=dd """
    im1h=dict()
    im2h=dict()

    for x in xrange(125):
        for y in xrange(125):
            im1h[x,y]=im1.getpixel((x,y))
            im2h[x,y]=im2.getpixel((x,y))
  

    #total=float(2*(dd-deltaY)*2*(dd-deltaY))
    cur=0.
    for dx in xrange(deltaX,2*dd-deltaY):
        for dy in xrange(deltaX,2*dd-deltaY):
       ##print "dx:",dx,"dy:",dy,"===================="
            cur+=1.
            ##print '\r\r\r',cur/total,
            if stitch(im1h,im2h,dx,dy):
                print "stiched at: ",dx,dy
                return dx,dy+1

    ##print "Can't stich!"
    return -1,-1

def equNull(a):
    return abs(a[0]-213)+abs(a[1]-194)+abs(a[2]-167)<50
       
def badBlock(i1,i2,a,b,c,d):
    ##print 'bb test',
    ##print i1[a[0],a[1]]," ",i1[b[0],b[1]]
    if equNull(i1[a[0],a[1]]) and equNull(i1[b[0],b[1]]):
        ##print '1>bb!'
        return True
    if equNull(i2[c[0],c[1]]) and equNull(i2[d[0],d[1]]):
        ##print '2>bb!'
        return True


def stitch(im1hash,im2hash,dx,dy):
    a,b,c,d=calcCoords(dx,dy,125)

    x1c=a[0]
    y1c=a[1]
    
    x2c=c[0]
    y2c=c[1]
    stiched=0
    if badBlock(im1hash,im2hash,a,b,c,d):
        return False
    if equNull(im1hash[a[0],a[1]]) or equNull(im2hash[c[0],c[1]]):
        a,b,c,d=calcCoords(dx-1,dy,125)
    #one of upper left corners is a badBlock    
        ##print 'goes from down right'
        x1c=b[0]
        y1c=b[1]
    
        x2c=d[0]
        y2c=d[1]



        for i in xrange(a[0],b[0]):
            for j in xrange(a[1],b[1]):
        ##print "get 1 at", x1c,y1c

            #px2=im2hash[random.randint(c[0],d[0]),random.randint(c[1],d[1])]
                px2=im2hash[x2c,y2c]
                if equNull(px2):
                    continue
            
            #px1=im1hash[random.randint(a[0],b[0]),random.randint(a[1],b[1])]
                px1=im1hash[x1c,y1c]
                if equNull(px1):
                    continue
                    
                if abs(px1[2]-px2[2]) >5: # errr
        
            #v[dx,dy]=stiched
                    return False
                else:
                
                    stiched+=1
            ##print stiched
                    if stiched>100:#stop scanning if X match
            ##print dx,dy
                        return True  # remove for full scan
                #else:
                        #v[dx,dy]=stiched
                         
                y1c-=1
                y2c-=1

            y1c=b[1]
            y2c=d[1]
    
            x1c-=1
            x2c-=1
        return False


    for i in xrange(a[0],b[0]):
        for j in xrange(a[1],b[1]):
        
            px2=im2hash[x2c,y2c]
            if equNull(px2):
                continue
        
            px1=im1hash[x1c,y1c]
            if equNull(px1):
                continue
                    
            if abs(px1[2]-px2[2]) >5: # errr
        
            #v[dx,dy]=stiched
                return False
            else:
                
                stiched+=1
            ##print stiched
                if stiched>100:#stop scanning if X match
            ##print dx,dy
                    return True  # remove for full scan                
                         
            y1c+=1
            y2c+=1

        y1c=a[1]
        y2c=c[1]
    
        x1c+=1
        x2c+=1
    return False

def updateDict(path):
    r=dict()
    r=getShotList(path)
    ret=False
    rr=r.keys()
    rr.sort(fsc)
    global deltaX
    global deltaY
    for i in rr:
        if r[i]==(0, 0) or r[i]==None:
            try:
                im1=Image.open(path+i[0])
                im2=Image.open(path+i[1])
            except:
                return r,False
            ret=True
            print '\033[32m'+"Adding new"+'\033[0m',i[1],
            while(r[i]==(0,0) or r[i]==(-1,-1)):
                r[i]=overLaps(im1,im2,125)
                deltaX-=20
                deltaY-=20
            deltaX=deltaY=125

    file=open(path+"data.dict",'w')
    file.write(str(r))
    file.close()
    return r,ret

class synchronized(object):
    def __init__(self, *args):
        self.lock = Lock()
        
    def __call__(self, f):
        def lockedfunc(*args, **kwargs):
            try:
                self.lock.acquire()
                #print 'Acquired lock=>',currentThread()
                try:
                    return f(*args, **kwargs)
                except Exception, e:
                    raise
            finally:
                self.lock.release()
                #print 'Released lock=>',currentThread()

        return lockedfunc

@synchronized()
def saveUpdated(path):
    newData,changed=updateDict(path)
    if changed:
        im0=Image.new("RGB",(3000,3000),0)
        im0=mstich(newData,im0,path)
        name='R'+str(time.localtime()[0])+'-'+str("%02d" % time.localtime()[1])+'-'+str(time.localtime()[2])+'_'+time.ctime()[11:-5].replace(':','-')+'.png'
        im0.save(path+name)
        im0.save(backspath+str(time.localtime()[0])+'-'+str("%02d" % time.localtime()[1])+'-'+str(time.localtime()[2])+'_'+time.ctime()[11:-5].replace(':','-')+'.png')
        print '\033[32m'+'Saving...'+'\033[0m'+'\n\t'+path+name+' written!'
        '''for file in os.listdir(path):
            if file[0]=='R' and file!=name:
                os.remove(path+file)
        '''

class saveUpdatedThread(Thread):
    global path
    def run(self):
        
        while True:
            #print 'saveupdate!'
            saveUpdated(path)
            time.sleep(3)  


if __name__=='__main__':
    path=".\\map3\\"
    print '\033[1m'+'[map sticher]'+'\033[22m'
    sut = saveUpdatedThread()
    sut.start()
